package com.weng.cloud.service8881.concurrenct.algorithm.recursion.base;

import com.google.common.base.Stopwatch;
import com.weng.cloud.commons.base.TestUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author: weng
 * @Date: 2022/7/10
 * @Description: com.weng.cloud.service8881.concurrenct.algorithm.recursion.base
 */
@Slf4j
public abstract class PuzzleSample<P, M> {

    private final Stopwatch stopWatch = TestUtil.create();
    protected PuzzleSolver<P, M> solver;

    private PuzzleSample<P, M> timing() {
        TestUtil.start(stopWatch);
        return this;
    }

    private PuzzleSample<P, M> logUsingTime() {
        log.info("using time >>> {}", TestUtil.stopAndWatchNanos(stopWatch));
        return this;
    }

    public final void handle(PuzzleSolver<P, M> solver) throws InterruptedException {
        this.solver = solver;
        M[] moves = this.prepareData();
        this.initPuzzle(moves);
        if(this.illegalParams()){
            log.error("please check params !!!");
            //public class IllegalArgumentException extends RuntimeException
            throw new IllegalArgumentException();
        }
        this.timing();
        try {
            this.solver.solve();
        } catch (InterruptedException e) {
            log.error("thread was interrupted !!!");
            throw e;
        }
        this.logUsingTime();
        this.endHandle();
    }

    protected abstract M[] prepareData();

    protected abstract PuzzleSample<P, M> initPuzzle(M[] moves);

    protected abstract boolean illegalParams();

    protected abstract void endHandle();
}
